package cn.orangeframe.neon.application.tasks;

import cn.orangeframe.neon.application.run.WorkflowExecutor;
import cn.orangeframe.neon.domain.enums.TaskStatus;
import cn.orangeframe.neon.domain.enums.TaskType;
import cn.orangeframe.neon.domain.model.TaskModel;
import cn.orangeframe.neon.domain.model.WorkflowModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.List;

@Slf4j
@Component
public class Join extends WorkflowSystemTask {

    public Join() {
        super(TaskType.TASK_TYPE_JOIN);
    }

    @Override
    public void execute(WorkflowModel workflow, TaskModel task, WorkflowExecutor executor) {
        log.info("Executing join task: {},{}", task.getTaskReferenceName(), task.getTaskId());
        try {
            task.getLatch().await();
        } catch (InterruptedException e) {
            log.error("Error while executing join task: {},{}", task.getTaskReferenceName(), task.getTaskId(), e);
        }
        boolean allDone = true;
        List<String> joinOn = (List<String>) task.getInputData().get("joinOn");
        for (String joinOnRef : joinOn) {
            TaskModel forkedTask = workflow.getTaskByRefName(joinOnRef);
            if (forkedTask == null) {
                allDone = false;
                break;
            }
            TaskStatus taskStatus = forkedTask.getStatus();
            if (!taskStatus.isTerminal()) {
                allDone = false;
            }
        }

        if (allDone) {
            log.info("Completed join task: {},{}", task.getTaskReferenceName(), task.getTaskId());
            task.setStatus(TaskStatus.COMPLETED);
        }
    }
}
